package com.imooc.business.util.report;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * @Author Tim
 * @Description:
 * @Version 1.0
 */
public class CalendarUtil {
    private static final int[] LUNAR_INFO = new int[]{19416, 19168, 42352, 21717, 53856, 55632, 91476, 22176, 39632, 21970, 19168, 42422, 42192, 53840, 119381, 46400, 54944, 44450, 38320, 84343, 18800, 42160, 46261, 27216, 27968, 109396, 11104, 38256, 21234, 18800, 25958, 54432, 59984, 28309, 23248, 11104, 100067, 37600, 116951, 51536, 54432, 120998, 46416, 22176, 107956, 9680, 37584, 53938, 43344, 46423, 27808, 46416, 86869, 19872, 42448, 83315, 21200, 43432, 59728, 27296, 44710, 43856, 19296, 43748, 42352, 21088, 62051, 55632, 23383, 22176, 38608, 19925, 19152, 42192, 54484, 53840, 54616, 46400, 46496, 103846, 38320, 18864, 43380, 42160, 45690, 27216, 27968, 44870, 43872, 38256, 19189, 18800, 25776, 29859, 59984, 27480, 21952, 43872, 38613, 37600, 51552, 55636, 54432, 55888, 30034, 22176, 43959, 9680, 37584, 51893, 43344, 46240, 47780, 44368, 21977, 19360, 42416, 86390, 21168, 43312, 31060, 27296, 44368, 23378, 19296, 42726, 42208, 53856, 60005, 54576, 23200, 30371, 38608, 19415, 19152, 42192, 118966, 53840, 54560, 56645, 46496, 22224, 21938, 18864, 42359, 42160, 43600, 111189, 27936, 44448};
    private static final int MIN_YEAR = 1900;
    private static final int MAX_YEAR = 2049;
    private static boolean isLeapYear;
    private static final String START_DATE = "1900-01-30";
    public static final String SPRING_SEASON = "春季";
    public static final String SPRING_TYPE = "1";
    public static final String FALL_SEASON = "秋季";
    public static final String FALL_TYPE = "2";
    public static final String YEAR = "年";
    public static final String SPRING_FIRSTDAY = "-01-16";
    public static final String SPRING_LASTDAY = "-08-31";
    public static final String FALL_FIRSTDAY = "-09-01";
    public static final String FALL_LASTDAY = "-01-15";
    public static final String YEAR_FIRSTDAY = "-01-01";

    public CalendarUtil() {
    }

    private static int getLeapMonth(int year) {
        return LUNAR_INFO[year - 1900] & 15;
    }

    private static int getLeapMonthDays(int year) {
        if (getLeapMonth(year) != 0) {
            return (LUNAR_INFO[year - 1900] & 983040) == 0 ? 29 : 30;
        } else {
            return 0;
        }
    }

    private static int getMonthDays(int lunarYeay, int month) throws Exception {
        if (month <= 31 && month >= 0) {
            int bit = 1 << 16 - month;
            return (LUNAR_INFO[lunarYeay - 1900] & '\uffff' & bit) == 0 ? 29 : 30;
        } else {
            throw new Exception("月份有错！");
        }
    }

    private static int getYearDays(int year) {
        int sum = 348;

        for(int i = 32768; i >= 8; i >>= 1) {
            if ((LUNAR_INFO[year - 1900] & '\ufff0' & i) != 0) {
                ++sum;
            }
        }

        return sum + getLeapMonthDays(year);
    }

    private static int daysBetween(Date startDate, Date endDate) {
        long between_days = (endDate.getTime() - startDate.getTime()) / 86400000L;
        return Integer.parseInt(String.valueOf(between_days));
    }

    public static String lunarToSolar(String lunarDate, boolean leapMonthFlag) throws Exception {
        int lunarYear = Integer.parseInt(lunarDate.substring(0, 4));
        int lunarMonth = Integer.parseInt(lunarDate.substring(5, 7));
        int lunarDay = Integer.parseInt(lunarDate.substring(8, 10));
        int offset = 0;

        int leapMonth;
        int temp;
        for(leapMonth = 1900; leapMonth < lunarYear; ++leapMonth) {
            temp = getYearDays(leapMonth);
            offset += temp;
        }

        leapMonth = getLeapMonth(lunarYear);
        int tempMonthDaysCount;
        if (leapMonth != 0 && lunarMonth >= leapMonth && (lunarMonth != leapMonth || leapMonthFlag)) {
            for(temp = 1; temp < lunarMonth; ++temp) {
                tempMonthDaysCount = getMonthDays(lunarYear, temp);
                offset += tempMonthDaysCount;
            }

            if (lunarMonth > leapMonth) {
                temp = getLeapMonthDays(lunarYear);
                offset += temp;
                if (lunarDay > getMonthDays(lunarYear, lunarMonth)) {
                    throw new Exception("不合法的农历日期！");
                }

                offset += lunarDay;
            } else {
                temp = getMonthDays(lunarYear, lunarMonth);
                offset += temp;
                if (lunarDay > getLeapMonthDays(lunarYear)) {
                    throw new Exception("不合法的农历日期！");
                }

                offset += lunarDay;
            }
        } else {
            for(temp = 1; temp < lunarMonth; ++temp) {
                tempMonthDaysCount = getMonthDays(lunarYear, temp);
                offset += tempMonthDaysCount;
            }

            if (lunarDay > getMonthDays(lunarYear, lunarMonth)) {
                throw new Exception("不合法的农历日期！");
            }

            offset += lunarDay;
        }

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Date myDate = null;
        myDate = formatter.parse("1900-01-30");
        Calendar c = Calendar.getInstance();
        c.setTime(myDate);
        c.add(5, offset);
        myDate = c.getTime();
        return formatter.format(myDate);
    }

    public static String solarToLunar(String solarDate) throws Exception {
        int temp = 0;
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Date myDate = null;
        Date startDate = null;

        try {
            myDate = formatter.parse(solarDate);
            startDate = formatter.parse("1900-01-30");
        } catch (ParseException var13) {
            var13.printStackTrace();
        }

        int offset = daysBetween(startDate, myDate);

        int i;
        for(i = 1900; i <= 2049; ++i) {
            temp = getYearDays(i);
            if (offset - temp < 1) {
                break;
            }

            offset -= temp;
        }

        int lunarYear = i;
        int leapMonth = getLeapMonth(i);
        if (leapMonth > 0) {
            isLeapYear = true;
        } else {
            isLeapYear = false;
        }

        for(i = 1; i <= 12; ++i) {
            if (i == leapMonth + 1 && isLeapYear) {
                temp = getLeapMonthDays(lunarYear);
                isLeapYear = false;
                --i;
            } else {
                temp = getMonthDays(lunarYear, i);
            }

            offset -= temp;
            if (offset <= 0) {
                break;
            }
        }

        offset += temp;
        String month = i + "";
        String d = offset + "";
        if (month.length() == 1) {
            month = "0" + i;
        }

        if (d.length() == 1) {
            d = "0" + d;
        }

        return lunarYear + "-" + month + "-" + d + "";
    }

    public static String getSeasonStartTime(Date date) {
        try {
            String season = getSeasonType(date);
            String year = DateUtil.format(date, "yyyy");
            if ("2".equals(season)) {
                year = getLunarToSolarYear(date);
                return year + "-09-01";
            } else {
                return getSpringFirstDay(year);
            }
        } catch (Exception var3) {
            var3.printStackTrace();
            return null;
        }
    }

    public static String getSeasonEndTime(Date date) {
        String season = getSeasonType(date);
        String year = DateUtil.format(date, "yyyy");
        if ("2".equals(season)) {
            Integer i = null;
            if (year != null) {
                i = Integer.parseInt(year);
                Date day = DateUtil.parse(year + "-08-31", "yyyy-MM-dd");
                if (date.compareTo(day) > 0) {
                    i = i + 1;
                }
            }

            return getFallLastEndDay(i != null ? String.valueOf(i) : year);
        } else {
            return year + "-08-31";
        }
    }

    public static String getSeasonStartTime(String year, String seasonType) {
        return "2".equals(seasonType) ? year + "-09-01" : year + "-01-16";
    }

    public static String getSeasonEndTime(String year, String seasonType) {
        return "2".equals(seasonType) ? getFallLastDay(year) : year + "-08-31";
    }

    public static String getFallLastDay(String year) {
        try {
            Date date = new Date();
            Date startDate = DateUtil.parse(year + "-01-01", "yyyy-MM-dd");
            Date endDate = DateUtil.parse(lunarToSolar(year + "-01-15", false), "yyyy-MM-dd");
            return date.after(startDate) && date.before(endDate) ? lunarToSolar(year + "-01-15", false) : lunarToSolar(Integer.parseInt(year) + 1 + "-01-15", false);
        } catch (Exception var4) {
            var4.printStackTrace();
            return null;
        }
    }

    private static String getFallLastEndDay(String year) {
        try {
            return lunarToSolar(year + "-01-15", false);
        } catch (Exception var2) {
            var2.printStackTrace();
            return null;
        }
    }

    public static String getSpringFirstDay(String year) {
        try {
            return lunarToSolar(year + "-01-16", false);
        } catch (Exception var2) {
            var2.printStackTrace();
            return null;
        }
    }

    public static String getSeasonType(Date date) {
        try {
            String year = DateUtil.format(date, "yyyy");
            Date day = DateUtil.parse(year + "-08-31", "yyyy-MM-dd");
            Date lunarThisDay = DateUtil.parse(solarToLunar(DateUtil.format(date, "yyyy-MM-dd")), "yyyy-MM-dd");
            Date lunarDay = DateUtil.parse(year + "-01-16", "yyyy-MM-dd");
            return date.compareTo(day) < 0 && lunarThisDay.compareTo(lunarDay) >= 0 ? "1" : "2";
        } catch (Exception var5) {
            var5.printStackTrace();
            return "1";
        }
    }

    public static String getSeasonType(String seasonName) {
        try {
            return "春季".equals(seasonName) ? "1" : "2";
        } catch (Exception var2) {
            var2.printStackTrace();
            return "1";
        }
    }

    public static String getSeasonName(Date date) {
        return getSeasonNameByType(getSeasonType(date));
    }

    public static String getSeasonNameByType(String type) {
        return "1".equals(type) ? "春季" : "秋季";
    }

    public static String getSeasonTitle(Date date) {
        try {
            String season = getSeasonType(date);
            String year = DateUtil.format(date, "yyyy");
            if (season.equals("2")) {
                year = getLunarToSolarYear(date);
                return year + "年" + "秋季";
            } else {
                return year + "年" + "春季";
            }
        } catch (Exception var3) {
            var3.printStackTrace();
            return "";
        }
    }

    public static String getSeasonTitle(String year, String season) {
        return season.equals("2") ? year + "年" + "秋季" : year + "年" + "春季";
    }

    public static String getThisSeason() {
        String season = getSeasonType(new Date());
        return season;
    }

    public static String getLastSeason() {
        String season = getSeasonType(new Date());
        return season.equals("2") ? "1" : "2";
    }

    public static String getYear(Date date) {
        String season = getSeasonType(date);
        String year = "";

        try {
            if (season.equals("2")) {
                year = getLunarToSolarYear(date);
            } else {
                year = DateUtil.format(date, "yyyy");
            }
        } catch (Exception var4) {
            var4.printStackTrace();
        }

        return year;
    }

    public static String getLastSeasonYear() {
        Date now = DateUtil.getNow();
        String year = getYear(now);
        String season = getSeasonType(now);
        return "1".equals(season) ? Integer.parseInt(year) - 1 + "" : year;
    }

    public static String getLastSeasonStartData() {
        Date now = DateUtil.getNow();
        String year = getYear(now);
        String season = getSeasonType(now);
        return "1".equals(season) ? Integer.parseInt(year) - 1 + "-09-01" : getSpringFirstDay(year);
    }

    public static String getLastSeasonEndData() {
        Date now = DateUtil.getNow();
        String year = getYear(now);
        String season = getSeasonType(now);
        return "1".equals(season) ? getFallLastEndDay(year) : year + "-08-31";
    }

    private static String getLunarToSolarYear(Date date) {
        String year = DateUtil.format(date, "yyyy");

        try {
            Date startDate = DateUtil.parse(year + "-01-01", "yyyy-MM-dd");
            Date endDate = DateUtil.getDayEndTime(DateUtil.parse(lunarToSolar(year + "-01-15", false), "yyyy-MM-dd"));
            if (date.after(startDate) && date.compareTo(endDate) <= 0) {
                year = Integer.parseInt(year) - 1 + "";
            }
        } catch (Exception var4) {
            var4.printStackTrace();
        }

        return year;
    }
}

